.data
# common declaration
.set DUMMY,		0x00000000


.set gdt_len,			3 * 8
.set code_sel,			0x08
.set data_sel,			0x10


.align 8
dummy:	.word 0x0000
	.word 0x0000
	.word 0x0000
	.word 0x0000

code:	.word 0xFFFF
	.word 0x0000
	.byte 0x00
	.byte 0x98
	.byte 0xCF
	.byte 0x00

data:	.word 0xFFFF
	.word 0x0000
	.byte 0x00
	.byte 0x92
	.byte 0xCF
	.byte 0x00

.align 4
stack: .fill 0x200, 0x00, 0x00


.code16
.section .text.init
.globl _start


# whole monitor entry
_start:

			# make all segments ready
			movw %cs,%ax
			movw %ax,%ss
			movw %ax,%ds
			movw %ax,%es
			
			# align sp to 4 bytes
			movw $stack,%sp
			addw $0x200,%sp


.extern get_memory_e820,fast_a20,a20_status,load_kernel
_start.0:		
			# make all common registers clean
			xorl %eax,%eax
			xorl %ecx,%ecx
			xorl %edx,%edx
			xorl %ebx,%ebx
			xorl %edi,%edi
			xorl %esi,%esi
			xorl %ebp,%ebp
			
			call get_memory_e820


			call fast_a20
			call a20_status
			jnz _load_kernel
#####################################################################
#                    A20 open failed , halt here		    #
#####################################################################
			hlt
			
			
_load_kernel:
			call load_kernel
			
pre_protect:
			movw $gdt_len,(%esp)
			
			movl $0x00001000,%eax
			addl $dummy,%eax		
			movl %eax, 2(%esp)
			lgdtl (%esp)
			
			movl %cr0,%eax
			orl $0x00000001,%eax
			movl %eax,%cr0
		
			jmpl $code_sel, $en_protect + 0x1000
			
.code32
.section .text
.extern kern_entry_offset,move_kernel,pre_set_page
en_protect:
			movw $data_sel, %ax
			movw %ax, %ds
			movw %ax, %ss
			
			movl $stack, %esp
			addl $0x1000, %esp	# base address of monitor
			addl $0x200, %esp	# make esp point the high memory of stack
			
			call kern_entry_offset
			call move_kernel

			call pre_set_page

.extern pg_dir
setup_page:			
			movl $pg_dir, %eax
			addl $0x1000, %eax
			movl %eax, %cr3
		
			movl %cr0, %eax
			orl $0x80000000, %eax
			movl %eax, %cr0
		
			jmp en_pre_page

.extern sys_info 	
en_pre_page:
			movl $sys_info, (%esp)
			movl $0xc0000000, %eax
																			
to_kernel:		
			jmp *%eax

			
			
#####################################################################
#                    no return here				    #
#####################################################################
			hlt



# EOF

